package com.sqlcheck.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sqlcheck.dto.ai.RuleVerificationRequest;
import com.sqlcheck.dto.ai.RuleVerificationResponse;
import com.sqlcheck.entity.CompatibilityRule;
import com.sqlcheck.entity.ScanResult;
import com.sqlcheck.entity.ScanTask;
import com.sqlcheck.entity.SqlStatement;
import com.sqlcheck.repository.CompatibilityRuleRepository;
import com.sqlcheck.repository.ScanResultRepository;
import com.sqlcheck.repository.ScanTaskRepository;
import com.sqlcheck.repository.SqlStatementRepository;
import com.sqlcheck.dto.request.LLMOptimizeRequest;
import com.sqlcheck.dto.response.LLMApiResponse;
import com.sqlcheck.service.LLMApiService;
import com.sqlcheck.service.AIEnhancementService;
import com.sqlcheck.service.AIEnhancementPromptManager;
import com.sqlcheck.service.SqlBatchSplitter;
import com.sqlcheck.service.ProgressCallback;
import com.sqlcheck.config.LLMConfiguration;
import com.sqlcheck.util.JsonUtils;
import com.sqlcheck.config.SimpleAIParallelConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * AI增强验证服务实现
 * 负责使用AI对规则分析结果进行二次验证和增强
 * 
 * @author Claude
 * @version v1.0
 * @since 2025-01-09
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AIEnhancementServiceImpl implements AIEnhancementService {

    private final SqlBatchSplitter sqlBatchSplitter;
    private final LLMApiService llmApiService;
    private final AIEnhancementPromptManager promptManager;
    private final ScanResultRepository scanResultRepository;
    private final SqlStatementRepository sqlStatementRepository;
    private final ScanTaskRepository scanTaskRepository;
    private final CompatibilityRuleRepository compatibilityRuleRepository;
    private final LLMConfiguration llmConfiguration;
    private final SimpleAIParallelConfig parallelConfig;

    @Autowired(required = false)
    @Qualifier("aiVerificationExecutor")
    private ThreadPoolTaskExecutor aiExecutor;

    @Value("${ai.verification.enabled:true}")
    private boolean verificationEnabled;

    @Value("${ai.verification.timeout-seconds:60}")
    private int timeoutSeconds;

    @Value("${ai.verification.max-retries:2}")
    private int maxRetries;

    @Value("${ai.verification.max-issues-per-task:20}")
    private int maxIssuesPerTask;

    @Value("${ai.verification.severity-priority:HIGH,MEDIUM,LOW}")
    private String severityPriority;

    @Value("${ai.verification.max-request-size:1048576}") // 1MB默认限制
    private int maxRequestSize;

    @Override
    public List<ScanResult> verifyRuleResults(Long taskId, List<ScanResult> ruleResults) {
        return verifyRuleResults(taskId, ruleResults, null);
    }

    @Override
    public List<ScanResult> verifyRuleResults(Long taskId, List<ScanResult> ruleResults,
            ProgressCallback progressCallback) {
        log.info("开始AI验证规则结果 - 任务ID: {}, 规则结果数: {}", taskId, ruleResults.size());

        if (!verificationEnabled) {
            log.info("AI验证功能已禁用，跳过验证");
            if (progressCallback != null) {
                progressCallback.onProgress(ruleResults.size(), ruleResults.size(), "AI验证功能已禁用，跳过验证");
            }
            return ruleResults;
        }

        if (ruleResults.isEmpty()) {
            log.info("没有规则结果需要验证");
            if (progressCallback != null) {
                progressCallback.onProgress(0, 0, "没有规则结果需要验证");
            }
            return ruleResults;
        }

        try {
            // 1. 按严重程度筛选问题，最多选择配置的数量
            if (progressCallback != null) {
                progressCallback.onProgress(0, ruleResults.size(), "开始按严重程度筛选规则结果...");
            }

            List<ScanResult> selectedResults = selectIssuesBySeverity(ruleResults, maxIssuesPerTask);
            log.info("按严重程度筛选后的问题数量: {} (原始: {}, 限制: {})",
                    selectedResults.size(), ruleResults.size(), maxIssuesPerTask);

            if (progressCallback != null) {
                progressCallback.onProgress(selectedResults.size(), ruleResults.size(),
                        String.format("筛选完成，选择%d个高优先级问题进行AI验证", selectedResults.size()));
            }

            // 2. 构建AI验证请求
            RuleVerificationRequest request = buildVerificationRequest(taskId, selectedResults);

            // 3. 使用PromptManager构建PROMPT并进行分批处理
            List<com.sqlcheck.model.SqlStatement> modelStatements = convertToModelStatements(request);
            String basePrompt = promptManager.buildVerificationPrompt(request);
            int basePromptTokens = promptManager.estimateTokenCount(basePrompt);

            // 检查是否需要分批（现在主要基于SQL数量，token限制作为辅助）
            int defaultMaxTokens = 20000; // 设置合理的默认token限制用于兜底
            if (sqlBatchSplitter.shouldUseBatchProcessing(modelStatements, defaultMaxTokens, basePromptTokens)) {
                return processBatchedVerification(taskId, request, modelStatements, basePrompt, progressCallback);
            } else {
                return processSingleVerification(taskId, request, progressCallback);
            }

        } catch (Exception e) {
            log.error("AI验证规则结果失败 - 任务ID: {}", taskId, e);
            if (progressCallback != null) {
                progressCallback.onProgress(ruleResults.size(), ruleResults.size(), "AI验证失败: " + e.getMessage());
            }
            // 验证失败不影响原结果，只记录错误
            markAiVerificationFailed(taskId, e.getMessage());
            return ruleResults;
        }
    }

    @Override
    public RuleVerificationRequest buildVerificationRequest(Long taskId, List<ScanResult> ruleResults) {
        log.debug("构建AI验证请求 - 任务ID: {}, 结果数: {}", taskId, ruleResults.size());

        // 1. 获取任务信息
        ScanTask task = scanTaskRepository.selectById(taskId);
        if (task == null) {
            throw new IllegalArgumentException("任务不存在: " + taskId);
        }

        // 2. 按statement_number分组规则结果
        Map<Integer, List<ScanResult>> groupedResults = ruleResults.stream()
                .filter(r -> r.getStatementNumber() != null && r.getRuleId() != null)
                .collect(Collectors.groupingBy(ScanResult::getStatementNumber));

        // 3. 获取相关SQL语句
        List<SqlStatement> sqlStatements = sqlStatementRepository.selectList(
                new QueryWrapper<SqlStatement>().eq("task_id", taskId));
        Map<Integer, SqlStatement> statementMap = sqlStatements.stream()
                .collect(Collectors.toMap(SqlStatement::getStatementNumber, s -> s));

        // 4. 获取规则详细信息
        Set<String> ruleIds = ruleResults.stream()
                .map(ScanResult::getRuleId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        List<CompatibilityRule> rules = compatibilityRuleRepository.selectList(
                new QueryWrapper<CompatibilityRule>().in("rule_id", ruleIds));
        Map<String, CompatibilityRule> ruleMap = rules.stream()
                .collect(Collectors.toMap(CompatibilityRule::getRuleId, r -> r));

        // 5. 构建验证请求
        List<RuleVerificationRequest.StatementVerificationItem> statements = new ArrayList<>();
        for (Map.Entry<Integer, List<ScanResult>> entry : groupedResults.entrySet()) {
            Integer statementNumber = entry.getKey();
            List<ScanResult> issues = entry.getValue();
            SqlStatement sqlStatement = statementMap.get(statementNumber);

            if (sqlStatement != null) {
                List<RuleVerificationRequest.RuleIssueItem> ruleIssues = issues.stream()
                        .map(result -> buildRuleIssueItem(result, ruleMap.get(result.getRuleId())))
                        .collect(Collectors.toList());

                statements.add(RuleVerificationRequest.StatementVerificationItem.builder()
                        .statementNumber(statementNumber)
                        .sqlContent(sqlStatement.getContent())
                        .sqlType(sqlStatement.getSqlType().name())
                        .sourceType(sqlStatement.getSourceType().name())
                        .sourceFile(sqlStatement.getSourceFile())
                        .lineNumber(sqlStatement.getLineNumber())
                        .detectedIssues(ruleIssues)
                        .build());
            }
        }

        return RuleVerificationRequest.builder()
                .taskId(taskId)
                .sourceDbType(task.getSourceDbType())
                .targetDbType(task.getTargetDbType())
                .statements(statements)
                .build();
    }

    @Override
    @Transactional
    public List<ScanResult> processVerificationResponse(RuleVerificationRequest request,
            RuleVerificationResponse aiResponse) {
        log.info("处理AI验证响应 - 任务ID: {}, 验证结果数: {}",
                request.getTaskId(), aiResponse.getVerificationResults().size());

        List<ScanResult> updatedResults = new ArrayList<>();

        // 验证AI响应
        validateAiResponse(aiResponse, request);

        // 创建AI验证结果映射
        Map<Integer, Map<String, RuleVerificationResponse.IssueVerificationResult>> aiResultMap = new HashMap<>();

        for (RuleVerificationResponse.StatementVerificationResult statementResult : aiResponse
                .getVerificationResults()) {
            Integer statementNumber = statementResult.getStatementNumber();
            Map<String, RuleVerificationResponse.IssueVerificationResult> issueMap = statementResult
                    .getIssueVerifications().stream()
                    .collect(Collectors.toMap(
                            RuleVerificationResponse.IssueVerificationResult::getRuleId,
                            v -> v));
            aiResultMap.put(statementNumber, issueMap);
        }

        // 处理每个原始规则结果
        for (RuleVerificationRequest.StatementVerificationItem statement : request.getStatements()) {
            Integer statementNumber = statement.getStatementNumber();
            Map<String, RuleVerificationResponse.IssueVerificationResult> aiIssueMap = aiResultMap.get(statementNumber);

            if (aiIssueMap != null) {
                for (RuleVerificationRequest.RuleIssueItem ruleIssue : statement.getDetectedIssues()) {
                    String ruleId = ruleIssue.getRuleId();
                    RuleVerificationResponse.IssueVerificationResult aiVerification = aiIssueMap.get(ruleId);

                    if (aiVerification != null) {
                        // 精确查找并更新scan_result记录
                        ScanResult existingResult = findScanResultForUpdate(request.getTaskId(), statementNumber,
                                ruleId);
                        if (existingResult != null) {
                            updateScanResultWithAiVerification(existingResult, aiVerification, aiResponse);
                            scanResultRepository.updateById(existingResult);
                            updatedResults.add(existingResult);

                            log.debug("更新规则验证结果 - statement:{}, rule:{}, confirmed:{}",
                                    statementNumber, ruleId, aiVerification.getRuleAnalysisConfirmed());
                        }
                    } else {
                        log.warn("AI未返回ruleId={}的验证结果", ruleId);
                    }
                }
            } else {
                log.warn("AI未返回statementNumber={}的验证结果", statementNumber);
            }
        }

        log.info("AI验证响应处理完成 - 更新了 {} 个结果", updatedResults.size());
        return updatedResults;
    }

    @Override
    public boolean shouldEnableAiVerification(Long taskId) {
        if (!verificationEnabled) {
            return false;
        }

        ScanTask task = scanTaskRepository.selectById(taskId);
        return task != null && task.getAiEnhancementEnabled() != null && task.getAiEnhancementEnabled();
    }

    @Override
    public void batchVerifyRuleResults(Long taskId) {
        // 使用配置的默认批次大小
        int defaultBatchSize = 15; // 可以从配置读取
        batchVerifyRuleResults(taskId, defaultBatchSize);
    }

    @Override
    public void batchVerifyRuleResults(Long taskId, int batchSize) {
        log.info("开始批量验证规则结果 - 任务ID: {}, 批次大小: {}", taskId, batchSize);

        if (!verificationEnabled) {
            log.info("AI验证功能已禁用，跳过批量验证");
            return;
        }

        // 查询所有待验证的规则结果
        List<ScanResult> allRuleResults = scanResultRepository.selectList(
                new QueryWrapper<ScanResult>()
                        .eq("task_id", taskId)
                        .eq("analysis_engine", "RULE")
                        .isNull("rule_analysis_confirmed")
                        .orderByAsc("statement_number"));

        if (allRuleResults.isEmpty()) {
            log.info("任务{}没有需要AI验证的规则结果", taskId);
            return;
        }

        log.info("找到 {} 个需要AI验证的规则结果", allRuleResults.size());

        // 先按严重程度筛选，限制验证数量
        List<ScanResult> selectedResults = selectIssuesBySeverity(allRuleResults, maxIssuesPerTask);

        if (selectedResults.size() < allRuleResults.size()) {
            log.info("按严重程度筛选后，验证问题数从 {} 减少到 {}", allRuleResults.size(), selectedResults.size());
        }

        try {
            // 使用智能分批逻辑而不是简单的数量分批
            performIntelligentBatchVerification(taskId, selectedResults);

        } catch (Exception e) {
            log.error("批量AI验证失败", e);
            markAiVerificationFailed(taskId, "批量AI验证失败: " + e.getMessage());
        }

        // 更新最终状态
        updateFinalAiStatus(taskId);
    }

    @Override
    public AiVerificationStats getVerificationStats(Long taskId) {
        // 执行统计查询
        Map<String, Object> stats = scanResultRepository.selectMaps(
                new QueryWrapper<ScanResult>()
                        .eq("task_id", taskId)
                        .isNotNull("rule_analysis_confirmed")
                        .select("COUNT(*) as total_verified," +
                                "SUM(CASE WHEN rule_analysis_confirmed = 1 THEN 1 ELSE 0 END) as confirmed_count," +
                                "SUM(CASE WHEN rule_analysis_confirmed = 0 THEN 1 ELSE 0 END) as rejected_count," +
                                "AVG(ai_confidence_score) as avg_confidence," +
                                "SUM(CASE WHEN ai_confidence_score >= 0.8 THEN 1 ELSE 0 END) as high_confidence_count,"
                                +
                                "SUM(CASE WHEN ai_confidence_score < 0.5 THEN 1 ELSE 0 END) as low_confidence_count"))
                .get(0);

        // 获取总规则问题数
        int totalRuleIssues = Math.toIntExact(scanResultRepository.selectCount(
                new QueryWrapper<ScanResult>()
                        .eq("task_id", taskId)
                        .eq("analysis_engine", "RULE")));

        return new AiVerificationStatsImpl(stats, totalRuleIssues);
    }

    /**
     * 处理分批验证
     */
    private List<ScanResult> processBatchedVerification(Long taskId, RuleVerificationRequest request,
            List<com.sqlcheck.model.SqlStatement> modelStatements, String basePrompt,
            ProgressCallback progressCallback) {

        log.info("开始分批AI验证 - 任务ID: {}, SQL数量: {}", taskId, modelStatements.size());

        // 使用分批器进行分批
        int defaultMaxTokens = 20000; // 设置合理的默认token限制用于兜底
        int basePromptTokens = sqlBatchSplitter.estimateTokenCount(basePrompt);
        List<SqlBatchSplitter.SqlBatch> batches = sqlBatchSplitter.splitIntoBatches(
                modelStatements, defaultMaxTokens, basePromptTokens);

        log.info("分批完成，共 {} 个批次", batches.size());

        // 判断是否使用并行处理
        if (shouldUseParallelProcessing(batches)) {
            return processBatchedVerificationParallel(taskId, request, batches, progressCallback);
        } else {
            return processBatchedVerificationSerial(taskId, request, batches, progressCallback);
        }
    }

    /**
     * 判断是否使用并行处理
     */
    private boolean shouldUseParallelProcessing(List<SqlBatchSplitter.SqlBatch> batches) {
        return parallelConfig.isParallelEnabled() 
                && aiExecutor != null 
                && batches.size() > 1;
    }

    /**
     * 并行处理分批验证
     */
    private List<ScanResult> processBatchedVerificationParallel(Long taskId, RuleVerificationRequest request,
            List<SqlBatchSplitter.SqlBatch> batches, ProgressCallback progressCallback) {
        
        log.info("使用并行模式进行AI验证 - 任务ID: {}, 批次数: {}", taskId, batches.size());
        
        SimpleBatchProgressTracker progressTracker = 
            new SimpleBatchProgressTracker(batches.size(), progressCallback, "AI增强验证");
        
        // 并行处理所有批次
        List<CompletableFuture<List<ScanResult>>> futures = batches.stream()
            .map(batch -> CompletableFuture
                .supplyAsync(() -> processSingleBatch(batch, request, progressTracker), aiExecutor)
                .exceptionally(throwable -> {
                    log.error("批次 {} 并行处理异常", batch.getBatchNumber(), throwable);
                    progressTracker.onBatchError(batch.getBatchNumber(), throwable.getMessage());
                    return Collections.emptyList();
                }))
            .collect(Collectors.toList());
        
        // 等待所有批次完成并收集结果
        List<ScanResult> allResults = futures.stream()
            .map(CompletableFuture::join)
            .flatMap(List::stream)
            .collect(Collectors.toList());
        
        // 全部完成后更新最终进度
        progressTracker.onAllBatchesCompleted(allResults.size());
        
        log.info("并行验证完成 - 总更新结果: {}", allResults.size());
        return allResults;
    }

    /**
     * 串行处理分批验证（原有逻辑，作为降级方案）
     */
    private List<ScanResult> processBatchedVerificationSerial(Long taskId, RuleVerificationRequest request,
            List<SqlBatchSplitter.SqlBatch> batches, ProgressCallback progressCallback) {
        
        log.info("使用串行模式进行AI验证 - 任务ID: {}, 批次数: {}", taskId, batches.size());

        List<ScanResult> allUpdatedResults = new ArrayList<>();

        // 逐批处理（原有逻辑）
        for (int i = 0; i < batches.size(); i++) {
            SqlBatchSplitter.SqlBatch batch = batches.get(i);
            try {
                log.info("处理验证批次 {}/{}, 包含 {} 个SQL",
                        i + 1, batches.size(), batch.getStatementCount());

                if (progressCallback != null) {
                    progressCallback.onProgress(i, batches.size(),
                            String.format("[AI增强验证] 正在处理第%d/%d个验证批次，包含%d个SQL",
                                    i + 1, batches.size(), batch.getStatementCount()));
                }

                // 为当前批次构建请求
                RuleVerificationRequest batchRequest = createBatchRequest(request, batch);

                // 执行AI验证
                RuleVerificationResponse batchResponse = callAiVerificationWithRetry(batchRequest);

                // 处理批次响应
                List<ScanResult> batchUpdatedResults = processVerificationResponse(batchRequest, batchResponse);
                allUpdatedResults.addAll(batchUpdatedResults);

            } catch (Exception e) {
                log.error("批次 {} 验证失败", i + 1, e);
                // 继续处理其他批次
            }
        }

        log.info("串行验证完成 - 总更新结果: {}", allUpdatedResults.size());
        return allUpdatedResults;
    }

    /**
     * 处理单个批次（用于并行处理）
     */
    private List<ScanResult> processSingleBatch(SqlBatchSplitter.SqlBatch batch, 
                                              RuleVerificationRequest request,
                                              SimpleBatchProgressTracker progressTracker) {
        try {
            log.debug("开始处理批次 {} (包含 {} 个SQL)", batch.getBatchNumber(), batch.getStatementCount());
            
            RuleVerificationRequest batchRequest = createBatchRequest(request, batch);
            RuleVerificationResponse response = callAiVerificationWithRetry(batchRequest);
            List<ScanResult> results = processVerificationResponse(batchRequest, response);
            
            // 批次完成，更新进度计数
            progressTracker.onBatchCompleted(batch.getBatchNumber());
            
            log.debug("批次 {} 处理完成，返回 {} 个结果", batch.getBatchNumber(), results.size());
            return results;
            
        } catch (Exception e) {
            log.error("批次 {} 处理失败", batch.getBatchNumber(), e);
            progressTracker.onBatchError(batch.getBatchNumber(), e.getMessage());
            return Collections.emptyList();
        }
    }

    /**
     * 处理单次验证（无需分批）
     */
    private List<ScanResult> processSingleVerification(Long taskId, RuleVerificationRequest request,
            ProgressCallback progressCallback) {
        log.info("使用单次模式进行AI验证 - 任务ID: {}", taskId);

        try {
            if (progressCallback != null) {
                progressCallback.onProgress(0, 1, "发送AI验证请求...");
            }

            RuleVerificationResponse aiResponse = callAiVerificationWithRetry(request);

            if (progressCallback != null) {
                progressCallback.onProgress(1, 1, "AI验证完成，正在处理响应结果");
            }

            return processVerificationResponse(request, aiResponse);

        } catch (Exception e) {
            log.error("单次AI验证失败 - 任务ID: {}", taskId, e);
            throw e;
        }
    }

    /**
     * 调用AI验证（带重试）
     */
    private RuleVerificationResponse callAiVerificationWithRetry(RuleVerificationRequest request) {
        String prompt = promptManager.buildVerificationPrompt(request);
        log.debug("发送AI增强验证请求 - PROMPT长度: {} 字符", prompt.length());

        // 预估请求体大小（粗略估算）
        int estimatedRequestSize = prompt.length() * 4; // UTF-8最多4字节/字符，加上JSON结构开销
        if (estimatedRequestSize > maxRequestSize) {
            log.error("AI验证请求过大: 估算{}字节，超过限制{}字节 - 任务ID: {}",
                    estimatedRequestSize, maxRequestSize, request.getTaskId());
            throw new RuntimeException("AI验证请求过大，估算" + (estimatedRequestSize / 1024) + "KB，超过限制"
                    + (maxRequestSize / 1024) + "KB。请减少验证项目数量或使用分批处理。");
        }

        Exception lastException = null;
        for (int attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                // 获取LLM配置
                LLMOptimizeRequest.LLMConfig config = buildLLMConfig();

                log.debug("使用LLM配置 - 提供商: {}, 模型: {}", config.getProvider(), config.getModelName());

                // 调用LLM API
                LLMApiResponse apiResponse = llmApiService.callLLM(prompt, config);

                // 检查API响应
                if (apiResponse == null) {
                    throw new RuntimeException("LLM API返回null响应");
                }

                if (!apiResponse.isSuccess()) {
                    log.warn("LLM API调用失败，错误信息: {}", apiResponse.getErrorMessage());

                    throw new RuntimeException("LLM API调用失败: " + apiResponse.getErrorMessage());
                }

                String rawResponse = apiResponse.getContent();
                if (rawResponse == null || rawResponse.trim().isEmpty()) {
                    throw new RuntimeException("LLM API返回空内容");
                }

                log.debug("收到AI响应 - 长度: {} 字符", rawResponse.length());

                // 解析AI响应
                RuleVerificationResponse response = parseAiVerificationResponse(rawResponse);
                if (response == null) {
                    throw new RuntimeException("AI响应解析结果为null");
                }

                // 验证响应
                validateAiResponse(response, request);

                log.info("AI验证成功 - 第{}次尝试", attempt);
                return response;

            } catch (Exception e) {
                lastException = e;
                log.warn("AI验证第{}次尝试失败: {}", attempt, e.getMessage());

                if (attempt < maxRetries) {
                    try {
                        Thread.sleep(1000 * attempt); // 指数退避
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new RuntimeException("验证过程被中断", ie);
                    }
                }
            }
        }

        throw new RuntimeException("AI验证失败，已重试" + maxRetries + "次", lastException);
    }

    /**
     * 构建LLM配置
     */
    private LLMOptimizeRequest.LLMConfig buildLLMConfig() {
        // 获取默认提供商配置
        String providerName = llmConfiguration.getDefaultProviderName();
        LLMConfiguration.ProviderConfig providerConfig = llmConfiguration.getDefaultProviderConfig();

        if (providerConfig == null) {
            throw new RuntimeException("未找到默认LLM提供商配置: " + providerName);
        }

        // 选择模型
        String modelName = providerConfig.getDefaultModel();
        if (modelName == null && providerConfig.getModels() != null && !providerConfig.getModels().isEmpty()) {
            modelName = providerConfig.getModels().get(0).getName();
        }

        if (modelName == null) {
            throw new RuntimeException("未找到可用的模型配置");
        }

        // 获取模型的最大token限制
        Integer maxTokens = 8000; // 默认值
        if (providerConfig.getModels() != null) {
            for (LLMConfiguration.ModelConfig model : providerConfig.getModels()) {
                if (modelName.equals(model.getName()) && model.getMaxTokens() != null) {
                    // 暂时限制为8000以避免服务器错误
                    maxTokens = Math.min(model.getMaxTokens(), 8000);
                    break;
                }
            }
        }

        log.debug("使用模型: {}, 最大tokens: {}", modelName, maxTokens);

        return LLMOptimizeRequest.LLMConfig.builder()
                .provider(providerName)
                .modelName(modelName)
                .temperature(providerConfig.getTemperature() != null ? providerConfig.getTemperature() : 0.1)
                .maxTokens(maxTokens) // 使用配置的最大token数
                .headers(providerConfig.getHeaders())
                .parameters(providerConfig.getAdditionalParams())
                .build();
    }

    /**
     * 解析AI验证响应
     */
    private RuleVerificationResponse parseAiVerificationResponse(String rawResponse) {
        try {
            // 预处理响应内容，提取JSON部分
            String jsonContent = extractJsonFromResponse(rawResponse);

            log.debug("提取的JSON内容长度: {} 字符", jsonContent.length());

            // 先尝试直接解析
            try {
                RuleVerificationResponse response = JsonUtils.jsonToObject(jsonContent, RuleVerificationResponse.class);
                if (response != null) {
                    log.debug("JSON解析成功，无需修复");
                    return response;
                }
            } catch (Exception e) {
                log.debug("首次JSON解析失败，准备修复: {}", e.getMessage());
            }

            // 检查JSON是否完整，如果不完整则修复
            if (!JsonUtils.isValidJson(jsonContent)) {
                log.warn("检测到不完整的JSON，尝试修复");
                jsonContent = repairIncompleteJson(jsonContent);

                // 修复后再次验证
                if (!JsonUtils.isValidJson(jsonContent)) {
                    log.error("JSON修复后仍然无效，使用兜底响应");
                    return createEmptyVerificationResponse();
                }
            }

            RuleVerificationResponse response = JsonUtils.jsonToObject(jsonContent, RuleVerificationResponse.class);
            if (response == null) {
                log.warn("修复后的JSON解析仍返回null，使用兜底响应");
                return createEmptyVerificationResponse();
            }

            return response;

        } catch (Exception e) {
            log.error("解析AI验证响应失败: {}", rawResponse.substring(0, Math.min(rawResponse.length(), 1000)), e);

            // 如果JSON解析失败，创建一个空的响应，避免整个流程中断
            log.warn("JSON解析失败，创建空的验证响应以保证流程继续");
            return createEmptyVerificationResponse();
        }
    }

    /**
     * 修复不完整的JSON
     */
    private String repairIncompleteJson(String incompleteJson) {
        if (incompleteJson == null || incompleteJson.trim().isEmpty()) {
            return "{}";
        }

        String json = incompleteJson.trim();

        // 统计大括号和方括号
        int openBraces = 0;
        int closeBraces = 0;
        int openBrackets = 0;
        int closeBrackets = 0;
        boolean inString = false;
        boolean escaped = false;

        for (int i = 0; i < json.length(); i++) {
            char c = json.charAt(i);

            if (escaped) {
                escaped = false;
                continue;
            }

            if (c == '\\') {
                escaped = true;
                continue;
            }

            if (c == '"') {
                inString = !inString;
                continue;
            }

            if (!inString) {
                if (c == '{')
                    openBraces++;
                else if (c == '}')
                    closeBraces++;
                else if (c == '[')
                    openBrackets++;
                else if (c == ']')
                    closeBrackets++;
            }
        }

        StringBuilder repairedJson = new StringBuilder(json);

        // 处理字符串截断：如果最后在字符串中但没有闭合引号
        if (inString) {
            log.warn("检测到未闭合的字符串，添加闭合引号");
            repairedJson.append("\"");
        }

        // 如果JSON以逗号结尾，移除它
        if (repairedJson.length() > 0 && repairedJson.charAt(repairedJson.length() - 1) == ',') {
            repairedJson.deleteCharAt(repairedJson.length() - 1);
        }

        // 处理截断后的不完整字段：如果最后一个字符不是标点符号，可能字段值被截断了
        char lastChar = repairedJson.length() > 0 ? repairedJson.charAt(repairedJson.length() - 1) : ' ';
        if (lastChar != '"' && lastChar != '}' && lastChar != ']' && lastChar != ','
                && !Character.isWhitespace(lastChar)) {
            log.warn("检测到可能的字段值截断，尝试清理");
            // 找到最后一个完整的字段
            int lastCompleteFieldEnd = findLastCompleteFieldEnd(repairedJson.toString());
            if (lastCompleteFieldEnd > 0 && lastCompleteFieldEnd < repairedJson.length() - 1) {
                repairedJson.setLength(lastCompleteFieldEnd);
                log.debug("截断到最后完整字段位置: {}", lastCompleteFieldEnd);
            }
        }

        // 补充缺失的右方括号
        for (int i = 0; i < (openBrackets - closeBrackets); i++) {
            repairedJson.append("]");
        }

        // 补充缺失的右大括号
        for (int i = 0; i < (openBraces - closeBraces); i++) {
            repairedJson.append("}");
        }

        String repaired = repairedJson.toString();
        log.info("JSON修复完成，原长度: {}, 修复后长度: {}", json.length(), repaired.length());
        log.debug("修复后的JSON片段: {}", repaired.substring(0, Math.min(repaired.length(), 200)) + "...");

        return repaired;
    }

    /**
     * 找到最后一个完整字段的结束位置
     */
    private int findLastCompleteFieldEnd(String json) {
        int lastComma = json.lastIndexOf(',');
        int lastQuote = json.lastIndexOf('"');
        int lastBrace = json.lastIndexOf('}');
        int lastBracket = json.lastIndexOf(']');

        // 返回最后一个有效的结束位置
        return Math.max(Math.max(lastComma, lastQuote), Math.max(lastBrace, lastBracket));
    }

    /**
     * 创建空的验证响应
     */
    private RuleVerificationResponse createEmptyVerificationResponse() {
        RuleVerificationResponse response = new RuleVerificationResponse();
        response.setTaskId(0L);
        response.setOverallConfidence(BigDecimal.ZERO);
        response.setAnalysisTimestamp(java.time.LocalDateTime.now().toString());
        response.setVerificationResults(new java.util.ArrayList<>());
        log.info("创建了空的验证响应作为fallback");
        return response;
    }

    /**
     * 从AI响应中提取JSON内容
     */
    private String extractJsonFromResponse(String rawResponse) {
        if (rawResponse == null || rawResponse.trim().isEmpty()) {
            throw new RuntimeException("AI响应内容为空");
        }

        String response = rawResponse.trim();

        // 首先检查是否是OpenAI API格式的响应
        if (response.startsWith("{") && response.contains("\"choices\"")) {
            try {
                log.debug("检测到OpenAI API格式响应，尝试提取content字段");
                // 解析外层API响应
                Map<String, Object> apiResponse = JsonUtils.jsonToMap(response);

                if (apiResponse.containsKey("choices")) {
                    @SuppressWarnings("unchecked")
                    List<Map<String, Object>> choices = (List<Map<String, Object>>) apiResponse.get("choices");

                    if (choices != null && !choices.isEmpty()) {
                        Map<String, Object> firstChoice = choices.get(0);

                        // 检查finish_reason
                        String finishReason = (String) firstChoice.get("finish_reason");
                        if ("length".equals(finishReason)) {
                            log.warn("AI响应因长度限制被截断 (finish_reason: length)");
                        }

                        if (firstChoice.containsKey("message")) {
                            @SuppressWarnings("unchecked")
                            Map<String, Object> message = (Map<String, Object>) firstChoice.get("message");

                            if (message.containsKey("content")) {
                                String content = (String) message.get("content");
                                log.debug("从OpenAI API响应中提取content: {} 字符", content != null ? content.length() : 0);

                                if (content != null) {
                                    // 继续处理content中的JSON
                                    return extractJsonFromContent(content);
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                log.warn("解析OpenAI API格式失败，使用传统方法: {}", e.getMessage());
            }
        }

        // 传统的JSON提取方法
        return extractJsonFromContent(response);
    }

    /**
     * 从内容中提取JSON
     */
    private String extractJsonFromContent(String content) {
        if (content == null || content.trim().isEmpty()) {
            throw new RuntimeException("内容为空");
        }

        String response = content.trim();

        // 尝试提取被```json标记包围的JSON内容
        String jsonPattern = "```json\\s*\\n?([\\s\\S]*?)\\n?```";
        java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(jsonPattern);
        java.util.regex.Matcher matcher = pattern.matcher(response);

        if (matcher.find()) {
            String jsonContent = matcher.group(1).trim();
            log.debug("从markdown代码块中提取JSON: {} 字符", jsonContent.length());
            return jsonContent;
        }

        // 如果没有markdown包装，尝试查找JSON对象边界
        int jsonStart = response.indexOf('{');
        int jsonEnd = response.lastIndexOf('}');

        if (jsonStart >= 0 && jsonEnd > jsonStart) {
            String jsonContent = response.substring(jsonStart, jsonEnd + 1);
            log.debug("从响应中提取JSON对象: {} 字符", jsonContent.length());
            return jsonContent;
        }

        // 如果都找不到，直接返回原始响应
        log.warn("无法从响应中提取JSON，使用原始响应");
        return response;
    }

    /**
     * 按严重程度筛选问题，最多选择指定数量
     */
    private List<ScanResult> selectIssuesBySeverity(List<ScanResult> allResults, int maxCount) {
        if (allResults.size() <= maxCount) {
            return allResults;
        }

        log.info("问题数量超过限制 {} > {}，按严重程度筛选", allResults.size(), maxCount);

        // 解析严重程度优先级
        String[] priorities = severityPriority.split(",");
        Map<String, Integer> severityOrder = new HashMap<>();
        for (int i = 0; i < priorities.length; i++) {
            severityOrder.put(priorities[i].trim().toUpperCase(), priorities.length - i);
        }

        // 按严重程度排序，严重程度高的优先
        List<ScanResult> sortedResults = allResults.stream()
                .sorted((a, b) -> {
                    int orderA = severityOrder.getOrDefault(a.getSeverity().name(), 0);
                    int orderB = severityOrder.getOrDefault(b.getSeverity().name(), 0);
                    if (orderA != orderB) {
                        return Integer.compare(orderB, orderA); // 降序，高严重程度在前
                    }
                    // 严重程度相同时，按statement_number排序
                    return Integer.compare(
                            a.getStatementNumber() != null ? a.getStatementNumber() : 0,
                            b.getStatementNumber() != null ? b.getStatementNumber() : 0);
                })
                .collect(Collectors.toList());

        // 取前N个
        List<ScanResult> selected = sortedResults.subList(0, Math.min(maxCount, sortedResults.size()));

        // 统计筛选结果
        Map<ScanResult.Severity, Long> selectedCounts = selected.stream()
                .collect(Collectors.groupingBy(ScanResult::getSeverity, Collectors.counting()));

        log.info("筛选结果统计: {}", selectedCounts);
        return selected;
    }

    /**
     * 执行智能分批验证
     * 使用token估算的智能分批，而不是简单的数量分批
     */
    private void performIntelligentBatchVerification(Long taskId, List<ScanResult> selectedResults) {
        log.info("开始智能分批验证 - 任务ID: {}, 待验证问题数: {}", taskId, selectedResults.size());

        try {
            // 使用verifyRuleResults的智能分批逻辑
            verifyRuleResults(taskId, selectedResults);
            log.info("智能分批验证完成 - 任务ID: {}", taskId);

        } catch (Exception e) {
            log.error("智能分批验证失败 - 任务ID: {}", taskId, e);
            throw e;
        }
    }

    // 辅助方法实现...

    private RuleVerificationRequest.RuleIssueItem buildRuleIssueItem(ScanResult result, CompatibilityRule rule) {
        return RuleVerificationRequest.RuleIssueItem.builder()
                .ruleId(result.getRuleId())
                .ruleName(result.getRuleName())
                .category(rule != null ? rule.getCategory() : "UNKNOWN")
                .severity(result.getSeverity().name())
                .rulePattern(rule != null ? rule.getRulePattern() : "")
                .ruleDescription(rule != null ? rule.getDescription() : result.getIssueDescription())
                .ruleSuggestion(rule != null ? rule.getSuggestion() : result.getSuggestion())
                .issueDescription(result.getIssueDescription())
                .exampleSql(rule != null ? rule.getExampleSql() : null)
                .suggestedSql(rule != null ? rule.getSuggestedSql() : result.getSuggestedSql())
                .build();
    }

    private ScanResult findScanResultForUpdate(Long taskId, Integer statementNumber, String ruleId) {
        return scanResultRepository.selectOne(
                new QueryWrapper<ScanResult>()
                        .eq("task_id", taskId)
                        .eq("statement_number", statementNumber)
                        .eq("rule_id", ruleId)
                        .eq("analysis_engine", "RULE"));
    }

    private void updateScanResultWithAiVerification(ScanResult result,
            RuleVerificationResponse.IssueVerificationResult aiVerification,
            RuleVerificationResponse overallResponse) {

        // 更新AI验证核心字段
        result.setRuleAnalysisConfirmed(aiVerification.getRuleAnalysisConfirmed());
        result.setAiIssueDescription(aiVerification.getAiIssueDescription());
        result.setAiConfidenceScore(aiVerification.getConfidence());
        result.setOptimizedSql(aiVerification.getOptimizedSql());
        result.setOptimizationExplanation(aiVerification.getAiSuggestion());

        // 构建AI验证详情Map
        try {
            Map<String, Object> verificationDetails = Map.of(
                    "ai_reasoning",
                    aiVerification.getVerificationReasoning() != null ? aiVerification.getVerificationReasoning() : "",
                    "ai_analysis_time", LocalDateTime.now().toString(),
                    "rule_confirmed", aiVerification.getRuleAnalysisConfirmed(),
                    "confidence_score", aiVerification.getConfidence() != null ? aiVerification.getConfidence() : 0.0,
                    "overall_confidence",
                    overallResponse.getOverallConfidence() != null ? overallResponse.getOverallConfidence() : 0.0,
                    "verification_method", "RULE_VERIFICATION");

            result.setAiVerificationDetails(verificationDetails);
        } catch (Exception e) {
            log.warn("无法构建AI验证详情，使用简化版本: {}", e.getMessage());
            Map<String, Object> fallbackDetails = Map.of("error", "详情构建失败");
            result.setAiVerificationDetails(fallbackDetails);
        }

        // 更新分析引擎标记
        result.setAnalysisEngine("AI_ENHANCED");
        result.setAiOptimized(true);
    }

    private void validateAiResponse(RuleVerificationResponse response, RuleVerificationRequest request) {
        if (!request.getTaskId().equals(response.getTaskId())) {
            throw new RuntimeException("AI响应taskId不匹配");
        }

        if (response.getVerificationResults() == null || response.getVerificationResults().isEmpty()) {
            throw new RuntimeException("AI响应缺少verificationResults");
        }
    }

    // 转换和辅助方法
    private List<com.sqlcheck.model.SqlStatement> convertToModelStatements(RuleVerificationRequest request) {
        return request.getStatements().stream()
                .map(s -> {
                    // 从数据库查询完整的SqlStatement实体
                    SqlStatement entity = sqlStatementRepository.selectOne(
                            new QueryWrapper<SqlStatement>()
                                    .eq("task_id", request.getTaskId())
                                    .eq("statement_number", s.getStatementNumber()));
                    
                    if (entity != null) {
                        // 转换为业务模型，保持完整字段信息
                        return com.sqlcheck.model.SqlStatement.builder()
                                .id(entity.getId())
                                .content(entity.getContent())
                                .sourceFile(entity.getSourceFile())
                                .lineNumber(entity.getLineNumber())
                                .columnNumber(entity.getColumnNumber())
                                .sqlType(convertSqlType(entity.getSqlType()))
                                .sourceType(convertSourceType(entity.getSourceType()))
                                .className(entity.getClassName())
                                .methodName(entity.getMethodName())
                                .isNativeQuery(entity.getIsNativeQuery())
                                .isDerivedQuery(entity.getIsDerivedQuery())
                                .statementNumber(entity.getStatementNumber())
                                .taskId(entity.getTaskId())
                                .contentHash(entity.getContentHash())
                                .ddlType(convertDdlType(entity.getDdlType()))
                                .javaAnnotationType(convertJavaAnnotationType(entity.getJavaAnnotationType()))
                                .mybatisXmlElement(convertMybatisXmlElement(entity.getMybatisXmlElement()))
                                .primaryTable(entity.getPrimaryTable())
                                .affectedTables(entity.getAffectedTables())
                                .databaseObjects(entity.getDatabaseObjects())
                                .extractionMetadata(entity.getExtractionMetadata())
                                .build();
                    } else {
                        // 兜底逻辑：使用请求中的基础信息
                        log.warn("未找到statement_number={}的SQL实体，使用请求数据创建简化模型", s.getStatementNumber());
                        return com.sqlcheck.model.SqlStatement.builder()
                                .id((long) s.getStatementNumber())
                                .statementNumber(s.getStatementNumber())
                                .content(s.getSqlContent())
                                .taskId(request.getTaskId())
                                .build();
                    }
                })
                .collect(Collectors.toList());
    }

    // 枚举转换辅助方法
    private com.sqlcheck.model.SqlStatement.SqlType convertSqlType(SqlStatement.SqlType entityType) {
        return entityType != null ? com.sqlcheck.model.SqlStatement.SqlType.valueOf(entityType.name()) : null;
    }

    private com.sqlcheck.model.SqlStatement.SourceType convertSourceType(SqlStatement.SourceType entityType) {
        return entityType != null ? com.sqlcheck.model.SqlStatement.SourceType.valueOf(entityType.name()) : null;
    }

    private com.sqlcheck.model.SqlStatement.DdlType convertDdlType(SqlStatement.DdlType entityType) {
        return entityType != null ? com.sqlcheck.model.SqlStatement.DdlType.valueOf(entityType.name()) : null;
    }

    private com.sqlcheck.model.SqlStatement.JavaAnnotationType convertJavaAnnotationType(SqlStatement.JavaAnnotationType entityType) {
        return entityType != null ? com.sqlcheck.model.SqlStatement.JavaAnnotationType.valueOf(entityType.name()) : null;
    }

    private com.sqlcheck.model.SqlStatement.MybatisXmlElement convertMybatisXmlElement(SqlStatement.MybatisXmlElement entityType) {
        return entityType != null ? com.sqlcheck.model.SqlStatement.MybatisXmlElement.valueOf(entityType.name()) : null;
    }

    private RuleVerificationRequest createBatchRequest(RuleVerificationRequest originalRequest,
            SqlBatchSplitter.SqlBatch batch) {

        // 从批次中的SQL语句创建子请求
        List<RuleVerificationRequest.StatementVerificationItem> batchStatements = originalRequest.getStatements()
                .stream()
                .filter(s -> batch.getSqlStatements().stream()
                        .anyMatch(bs -> bs.getStatementNumber().equals(s.getStatementNumber())))
                .collect(Collectors.toList());

        return RuleVerificationRequest.builder()
                .taskId(originalRequest.getTaskId())
                .sourceDbType(originalRequest.getSourceDbType())
                .targetDbType(originalRequest.getTargetDbType())
                .statements(batchStatements)
                .build();
    }

    private void updateFinalAiStatus(Long taskId) {
        // 更新最终AI验证状态
        log.info("更新最终AI验证状态 - 任务ID: {}", taskId);
    }

    private void markAiVerificationFailed(Long taskId, String errorMessage) {
        log.error("标记AI验证失败 - 任务ID: {}, 错误: {}", taskId, errorMessage);
    }

    /**
     * AI验证统计信息实现类
     */
    private static class AiVerificationStatsImpl implements AiVerificationStats {
        private final Map<String, Object> stats;
        private final int totalRuleIssues;

        public AiVerificationStatsImpl(Map<String, Object> stats, int totalRuleIssues) {
            this.stats = stats;
            this.totalRuleIssues = totalRuleIssues;
        }

        @Override
        public int getTotalRuleIssues() {
            return totalRuleIssues;
        }

        @Override
        public int getAiVerifiedCount() {
            return ((Number) stats.getOrDefault("total_verified", 0)).intValue();
        }

        @Override
        public int getAiConfirmedCount() {
            return ((Number) stats.getOrDefault("confirmed_count", 0)).intValue();
        }

        @Override
        public int getAiRejectedCount() {
            return ((Number) stats.getOrDefault("rejected_count", 0)).intValue();
        }

        @Override
        public double getAverageConfidence() {
            Number avgConf = (Number) stats.getOrDefault("avg_confidence", 0.0);
            return avgConf != null ? avgConf.doubleValue() : 0.0;
        }

        @Override
        public int getHighConfidenceCount() {
            return ((Number) stats.getOrDefault("high_confidence_count", 0)).intValue();
        }

        @Override
        public int getLowConfidenceCount() {
            return ((Number) stats.getOrDefault("low_confidence_count", 0)).intValue();
        }
    }
}